/*
 * Copyright (c) 2023 iQi.Co.Ltd. All rights reserved.
 */
 
using System.Collections.Generic;
using NetProtocol.POD;
using NetProtocol.Enum;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.GamePlay;
using IQIGame.Onigao.Framework;
using Cysharp.Threading.Tasks;
using System;
using static IQIGame.Onigao.Game.MessageWrapper;

namespace NetProtocol.Client {
	/// <summary>
	/// 关卡
	/// module : level
	/// </summary>
	public interface CNetLevel : INetClientModule {
		
		public ISession GetSession();
	
		Dictionary<int, INetClientModule.Package2MessageWrapper> INetClientModule.GetModuleFunction()
        {
            MessageFunction requestEnterResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<RequestEnterResultData>)wrapper;
                SC_requestEnterResult(session, ref _wrapper.message);
                MessageWrapperPool<RequestEnterResultData>.Put(_wrapper);
            };
            MessageFunction localRequestSaveResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<LocalRequestSaveResultData>)wrapper;
                SC_localRequestSaveResult(session, ref _wrapper.message);
                MessageWrapperPool<LocalRequestSaveResultData>.Put(_wrapper);
            };
            MessageFunction localNotifyCreateLevel_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<LocalNotifyCreateLevelData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.level_localNotifyCreateLevel, "Recv->" + _wrapper.message.ToString());
#endif
                SC_localNotifyCreateLevel(session, _wrapper.message.playerPOD, _wrapper.message.createLevelPOD);
                MessageWrapperPool<LocalNotifyCreateLevelData>.Put(_wrapper);
            };
            MessageFunction localNotifyShutdownLevel_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<LocalNotifyShutdownLevelData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.level_localNotifyShutdownLevel, "Recv->" + _wrapper.message.ToString());
#endif
                SC_localNotifyShutdownLevel(session, _wrapper.message.levelId);
                MessageWrapperPool<LocalNotifyShutdownLevelData>.Put(_wrapper);
            };
            MessageFunction localS2CNotifyDataSyncEvent_Delegate = (session, wrapper) =>
            {
            var _wrapper = (MessageWrapper<LocalS2CNotifyDataSyncEventData>)wrapper; 
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.level_localS2CNotifyDataSyncEvent, "Recv->" + _wrapper.message.ToString());
#endif
                SC_localS2CNotifyDataSyncEvent(session, _wrapper.message.eventPOD);
                MessageWrapperPool<LocalS2CNotifyDataSyncEventData>.Put(_wrapper);
            };
            MessageFunction getLevelSaveDataResult_Delegate = (session, wrapper) =>
            {
            	var _wrapper = (MessageWrapper<GetLevelSaveDataResultData>)wrapper;
                SC_getLevelSaveDataResult(session, ref _wrapper.message);
                MessageWrapperPool<GetLevelSaveDataResultData>.Put(_wrapper);
            };
        
            Dictionary<int, INetClientModule.Package2MessageWrapper> retDic = new()
            {
                {NetMessageId.level_requestEnterResult, (session, package) => {
                	var result = MessageWrapperPool<RequestEnterResultData>.Get();
                	result.Init(session, requestEnterResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.level_localRequestSaveResult, (session, package) => {
                	var result = MessageWrapperPool<LocalRequestSaveResultData>.Get();
                	result.Init(session, localRequestSaveResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.level_localNotifyCreateLevel, (session, package) => {
                	var result = MessageWrapperPool<LocalNotifyCreateLevelData>.Get();
                	result.Init(session, localNotifyCreateLevel_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.level_localNotifyShutdownLevel, (session, package) => {
                	var result = MessageWrapperPool<LocalNotifyShutdownLevelData>.Get();
                	result.Init(session, localNotifyShutdownLevel_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.level_localS2CNotifyDataSyncEvent, (session, package) => {
                	var result = MessageWrapperPool<LocalS2CNotifyDataSyncEventData>.Get();
                	result.Init(session, localS2CNotifyDataSyncEvent_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
                {NetMessageId.level_getLevelSaveDataResult, (session, package) => {
                	var result = MessageWrapperPool<GetLevelSaveDataResultData>.Get();
                	result.Init(session, getLevelSaveDataResult_Delegate);
                	result.FromPackage(package);
                	return result;
                }},
            };
            return retDic;
        }
#region Client-side Interface
		/// <summary>
        ///  本地模式会异步走到 notifyCreateLevel
        /// </summary>
		public void SC_requestEnterResult(ISession session, ref RequestEnterResultData message) 
		{
            _SC_requestEnterResult(session, ref message);
		}
		
		public void _SC_requestEnterResult(ISession session, ref RequestEnterResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.level_requestEnterResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.level_requestEnterResult, message.code);
			MsgAsyncAwaiter<RequestEnterResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        ///  保存成功/失败需要提示
        /// </summary>
		public void SC_localRequestSaveResult(ISession session, ref LocalRequestSaveResultData message) 
		{
            _SC_localRequestSaveResult(session, ref message);
		}
		
		public void _SC_localRequestSaveResult(ISession session, ref LocalRequestSaveResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.level_localRequestSaveResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.level_localRequestSaveResult, message.code);
			MsgAsyncAwaiter<LocalRequestSaveResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
		/// <summary>
        ///  通知创建本地关卡，并直接进入，进入后发送notifyEnterLevel
        /// </summary>
		protected void SC_localNotifyCreateLevel(ISession session, LogicPlayerPOD playerPOD, CreateLevelPOD createLevelPOD);
		/// <summary>
        ///  通知退出本地关卡(强制踢出)
        /// </summary>
		protected void SC_localNotifyShutdownLevel(ISession session, long levelId);
		/// <summary>
        ///  关卡数据同步事件
        /// </summary>
		protected void SC_localS2CNotifyDataSyncEvent(ISession session, DataSyncEventPOD eventPOD);
		/// <summary>
        /// 
        /// </summary>
		public void SC_getLevelSaveDataResult(ISession session, ref GetLevelSaveDataResultData message) 
		{
            _SC_getLevelSaveDataResult(session, ref message);
		}
		
		public void _SC_getLevelSaveDataResult(ISession session, ref GetLevelSaveDataResultData message)
		{
#if ENABLE_NET_LOG || UNITY_EDITOR
            NetProtocolHelper.ClientLog(NetMessageId.level_getLevelSaveDataResult, "Recv->" + message.ToString());
#endif
			NetProtocolHelper.endCallRequest?.Invoke(NetMessageId.level_getLevelSaveDataResult, message.code);
			MsgAsyncAwaiter<GetLevelSaveDataResultData>.Instance.CompleteMsgAwait(ref message);
		}
		
#endregion
#region Server-side Interface
		/// <summary>
        ///  请求进入关卡
        /// </summary>
    	public UniTask<RequestEnterResultData> CS_requestEnter(RequestEnterLevelPOD requestPOD)
        {
            return _CS_requestEnter(requestPOD);
        }
        
        public UniTask<RequestEnterResultData> _CS_requestEnter(RequestEnterLevelPOD requestPOD)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(RequestEnterResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.level_requestEnter, "Send->"+"Level.CS_requestEnter { "
				+ "requestPOD="
				+ requestPOD
				+" }");
#endif
        	UniTask<RequestEnterResultData> task = MsgAsyncAwaiter<RequestEnterResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_requestEnter(requestPOD));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.level_requestEnterResult);
			return task;
        }
		
		public static SendPackage Pack_for_requestEnter(RequestEnterLevelPOD requestPOD) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.level_requestEnter;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(requestPOD);
			return si_p;
		}
		/// <summary>
        ///  请求保存本地关卡 -- Save需要转发到Game服
        /// </summary>
    	public UniTask<LocalRequestSaveResultData> CS_localRequestSave(RequestSaveLevelPOD requestSaveLevelPOD)
        {
            return _CS_localRequestSave(requestSaveLevelPOD);
        }
        
        public UniTask<LocalRequestSaveResultData> _CS_localRequestSave(RequestSaveLevelPOD requestSaveLevelPOD)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(LocalRequestSaveResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.level_localRequestSave, "Send->"+"Level.CS_localRequestSave { "
				+ "requestSaveLevelPOD="
				+ requestSaveLevelPOD
				+" }");
#endif
        	UniTask<LocalRequestSaveResultData> task = MsgAsyncAwaiter<LocalRequestSaveResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_localRequestSave(requestSaveLevelPOD));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.level_localRequestSaveResult);
			return task;
        }
		
		public static SendPackage Pack_for_localRequestSave(RequestSaveLevelPOD requestSaveLevelPOD) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.level_localRequestSave;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(requestSaveLevelPOD);
			return si_p;
		}
		/// <summary>
        ///  通知进入本地关卡	
        /// </summary>
    	public bool CS_localNotifyEnterLevel(long levelId) 
    	{
    		return _CS_localNotifyEnterLevel(levelId);
    	}
    	public bool _CS_localNotifyEnterLevel(long levelId)
        {
        	ISession session = GetSession();
        	if(session == null) return false;
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.level_localNotifyEnterLevel, "Send->"+"Level.CS_localNotifyEnterLevel { "
				+ "levelId="
				+ levelId
				+" }");
#endif
        	return session.SendPack(Pack_for_localNotifyEnterLevel(levelId));
        }
		
		public static SendPackage Pack_for_localNotifyEnterLevel(long levelId) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.level_localNotifyEnterLevel;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_long(levelId);
			return si_p;
		}
		/// <summary>
        ///  通知离开本地关卡	
        /// </summary>
    	public bool CS_localNotifyExitLevel(long levelId) 
    	{
    		return _CS_localNotifyExitLevel(levelId);
    	}
    	public bool _CS_localNotifyExitLevel(long levelId)
        {
        	ISession session = GetSession();
        	if(session == null) return false;
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.level_localNotifyExitLevel, "Send->"+"Level.CS_localNotifyExitLevel { "
				+ "levelId="
				+ levelId
				+" }");
#endif
        	return session.SendPack(Pack_for_localNotifyExitLevel(levelId));
        }
		
		public static SendPackage Pack_for_localNotifyExitLevel(long levelId) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.level_localNotifyExitLevel;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_long(levelId);
			return si_p;
		}
		/// <summary>
        ///  关卡数据同步事件
        /// </summary>
    	public bool CS_localC2SNotifyDataSyncEvent(DataSyncEventPOD eventPOD) 
    	{
    		return _CS_localC2SNotifyDataSyncEvent(eventPOD);
    	}
    	public bool _CS_localC2SNotifyDataSyncEvent(DataSyncEventPOD eventPOD)
        {
        	ISession session = GetSession();
        	if(session == null) return false;
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.level_localC2SNotifyDataSyncEvent, "Send->"+"Level.CS_localC2SNotifyDataSyncEvent { "
				+ "eventPOD="
				+ eventPOD
				+" }");
#endif
        	return session.SendPack(Pack_for_localC2SNotifyDataSyncEvent(eventPOD));
        }
		
		public static SendPackage Pack_for_localC2SNotifyDataSyncEvent(DataSyncEventPOD eventPOD) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.level_localC2SNotifyDataSyncEvent;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_pod(eventPOD);
			return si_p;
		}
		/// <summary>
        /// 获取关卡存档
        /// </summary>
    	public UniTask<GetLevelSaveDataResultData> CS_getLevelSaveData(int levelCid)
        {
            return _CS_getLevelSaveData(levelCid);
        }
        
        public UniTask<GetLevelSaveDataResultData> _CS_getLevelSaveData(int levelCid)
        {
        	ISession session = GetSession();
        	if(session == null) return UniTask.FromResult(default(GetLevelSaveDataResultData));
#if ENABLE_NET_LOG || UNITY_EDITOR
			NetProtocolHelper.ClientLog(NetMessageId.level_getLevelSaveData, "Send->"+"Level.CS_getLevelSaveData { "
				+ "levelCid="
				+ levelCid
				+" }");
#endif
        	UniTask<GetLevelSaveDataResultData> task = MsgAsyncAwaiter<GetLevelSaveDataResultData>.Instance.AddMsgAwait();
        	session.SendPack(Pack_for_getLevelSaveData(levelCid));
        	NetProtocolHelper.beginCallRequest?.Invoke(NetMessageId.level_getLevelSaveDataResult);
			return task;
        }
		
		public static SendPackage Pack_for_getLevelSaveData(int levelCid) 
		{
			SendPackage si_p = NetProtocolHelper.GetSendPackage();
			si_p.Header.Messagid = NetMessageId.level_getLevelSaveData;
			si_p.StartWrite();
			SOutputStream _out = si_p.OutputStream;
			_out.Write_int(levelCid);
			return si_p;
		}
#endregion
#region Messages
        public struct RequestEnterResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.level_requestEnterResult;}
            
            public override string ToString()
            {
                return "Level.requestEnterResult"+ ", code="+ code;
            }
        }
        public struct LocalRequestSaveResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
            }
            
            public int GetMessageId() {return NetMessageId.level_localRequestSaveResult;}
            
            public override string ToString()
            {
                return "Level.localRequestSaveResult"+ ", code="+ code;
            }
        }
        public struct LocalNotifyCreateLevelData : IReceiveMessage {
	        public LogicPlayerPOD playerPOD;
	        public CreateLevelPOD createLevelPOD;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                playerPOD = _in.HasRemaining() ? _in.Read_pod<LogicPlayerPOD>(LogicPlayerPOD.DynamicFactory) : default;
                createLevelPOD = _in.HasRemaining() ? _in.Read_pod<CreateLevelPOD>(CreateLevelPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.level_localNotifyCreateLevel;}
            
            public override string ToString()
            {
                return "Level.localNotifyCreateLevel"+ ", playerPOD="+ playerPOD+ ", createLevelPOD="+ createLevelPOD;
            }
        }
        public struct LocalNotifyShutdownLevelData : IReceiveMessage {
	        public long levelId;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                levelId = _in.HasRemaining() ? _in.Read_long() : default;
            }
            
            public int GetMessageId() {return NetMessageId.level_localNotifyShutdownLevel;}
            
            public override string ToString()
            {
                return "Level.localNotifyShutdownLevel"+ ", levelId="+ levelId;
            }
        }
        public struct LocalS2CNotifyDataSyncEventData : IReceiveMessage {
	        public DataSyncEventPOD eventPOD;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                eventPOD = _in.HasRemaining() ? _in.Read_pod<DataSyncEventPOD>(DataSyncEventPOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.level_localS2CNotifyDataSyncEvent;}
            
            public override string ToString()
            {
                return "Level.localS2CNotifyDataSyncEvent"+ ", eventPOD="+ eventPOD;
            }
        }
        public struct GetLevelSaveDataResultData : IReceiveMessage {
        	private int? _code;
        	public int code {get{return _code == null ? -1 : (int)_code;}private set{_code = value;}}
	        public GetLevelSavePOD saveData;
            public bool IsFail => _code != null && _code != 0;
            public bool IsSuccess =>_code != null && _code == 0;
            public bool IsCanceled => _code == null;
            public void FromPackage(ReceivePackage _package)
            {
                SInputStream _in = _package.InputStream;
                code = _in.HasRemaining() ? _in.Read_int() : default;
                saveData = _in.HasRemaining() ? _in.Read_pod<GetLevelSavePOD>(GetLevelSavePOD.DynamicFactory) : default;
            }
            
            public int GetMessageId() {return NetMessageId.level_getLevelSaveDataResult;}
            
            public override string ToString()
            {
                return "Level.getLevelSaveDataResult"+ ", code="+ code+ ", saveData="+ saveData;
            }
        }
    }
#endregion
}